﻿//#define ENABLE_EXCEL_COM
//#define ENABLE_ET_COM
//#define ENABLE_SharpZipLib
//#define ENABLE_AutoItX

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace suit_base
{
    public abstract class SuiteBase
    {
        public abstract string GetCommand();
        public abstract void Call();

        public static suit_base.SuiteBase[] GetSuitClasses()
        {
            return new suit_base.SuiteBase[] {
#if ENABLE_ET_COM
                new suit_bigmem.CBigMem(),
                new suit_etopen.CEtOpen(),
                new suite_recalcall.XRecalcAll(),       
                new suite_compare_cell.CompCell(),
                new suite_effciency_regression.CEffReg(),
#endif
#if ENABLE_EXCEL_COM
                new suite_recalc.CRecalc(),  
#endif

#if ENABLE_ET_COM
#if ENABLE_EXCEL_COM
                new suite_open_effciency_monitor.COpenEffMonitor(),
                new suite_sumif_combin.SumifTest(),
                new suite_condfmt_smoke.CondfmtTest(),
                new suit_relsheet_io.CRelSheetIO(),
#endif
#endif

#if ENABLE_SharpZipLib  
#if ENABLE_AutoItX
                new suit_calcchain.CalcChain(),
#endif
#endif
                           
                new suite_checkres.XCheckRes(),
                new suit_test.KTest(),/*Just for test*/
            };
        }
    }
}

namespace ET_Improve
{
    using System.Xml;
    using System.Timers;
    public delegate bool ConsoleCtrlDelegate(int dwCtrlType);

    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            try
            {
                ConsoleCtrl cc = new ConsoleCtrl();
                cc.ControlEvent += new ConsoleCtrl.ControlEventHandler(InputHandler);
                AppDomain.CurrentDomain.UnhandledException += (UnhandledExceptionEventHandler)delegate(object sender, UnhandledExceptionEventArgs e)
                {
                    ExitWithClean();
                };

                if (args.Length > 1)
                {
                    tool.Output.DumpWriteLine("参数个数错误");
                    return;
                }
                Global.LoadConfig();
                if (args.Length == 1)
                {
                    ProcessTool(args[0]);
                }
                else
                {
                    ProcessTool(null);
                }
            }
            catch (tool.ETImpException ex)
            {
                tool.Output.DumpWriteLine(ex.ToString());
            }
            catch (Exception ex)
            {
                tool.Output.DumpWriteLine(ex.ToString());
            }
            finally
            {
                ExitWithClean();
            }
        }

        internal static void ProcessTool(string sArg)
        {
            try
            {
                List<string> toolNameLst = null;
                if (sArg != null)
                {
                    toolNameLst = new List<string>(sArg.Split('+'));
                }
                suit_base.SuiteBase[] suites = suit_base.SuiteBase.GetSuitClasses();
                foreach (suit_base.SuiteBase x in suites)
                {
                    if (toolNameLst == null ||
                        toolNameLst.Contains(x.GetCommand()))
                    {
                        ET_Improve.Global.s_curCmdName = x.GetCommand();
                        x.Call();
                    }
                }
            }
            catch (System.Exception ex)
            {
            	throw ex;
            }
        }

        internal static void InputHandler(ConsoleCtrl.ConsoleEvent consoleEvent)
        {
            if (consoleEvent == ConsoleCtrl.ConsoleEvent.CtrlC)
            {
                ExitWithClean();
            }
        }

        internal static void ExitWithClean()
        {
#if ENABLE_ET_COM
            etOp.EtOp.KillAllEtProcess();
#endif
#if ENABLE_EXCEL_COM
            excelOp.ExcelOP.KillAllExcelProcess();
#endif
            System.Threading.Thread.Sleep(1000);
            tool.CTmpFileHlp.DeleteTmpFile(null);

            System.Environment.Exit(0);
        }
    }

    // 全局变量
    public class Global
    {
        public static string sConfigFile = "config.xml";
        public static readonly string CMD_OPENEFF   = "openeff";
        public static readonly string CMD_EFFREG    = "effreg";
        public static readonly string CMD_COMPCELL = "compcell";
        public static readonly string CMD_RECALC = "recalc";
        public static readonly string CMD_SUMIF_COMBIN = "sumifcombin";
        public static readonly string CMD_CONDFMT_SMOKE = "condfmtsmoke";
        public static readonly string CMD_RELSHEET = "relsheet";
        public static readonly string CMD_CALC_CHAIN = "calcchain";
        public static readonly string CMD_BIGMEM = "bigmem";
        public static readonly string CMD_ETOPEN = "etopen";
        public static readonly string CMD_TEST = "test";
        public static readonly string CMD_RECALCALL = "recalcall";
        public static readonly string CMD_CHECKRES = "checkres";

        public static string s_curCmdName;  //  当前程序执行的工具名称
        public static uint gTimeOut;
        public static string m_strDefaultDir;
        
        public static void LoadConfig()
        {
            try
            {
                foreach (XmlNode xn in tool.ConfigReader.GetElementList("Global"))
                {
                    if (xn.NodeType != XmlNodeType.Element)
                    {
                        continue;
                    }
                    XmlElement xe = (XmlElement)xn;
                    if (xe.Name == "TimeOut")
                    {
                        gTimeOut = uint.Parse(xe.InnerText);
                    }
#if ENABLE_AutoItX
                    else if (xe.Name == "KillRule")
                    {
                        autoIt.CAutoIt.AddKillRule(xe.GetAttribute("DlgClass"),
                                    xe.GetAttribute("DlgCaption"),
                                    xe.GetAttribute("DlgText"),
                                    xe.GetAttribute("Actions"));
                    }
#endif
                    else if (xe.Name == "default-log-dir")
                    {
                        m_strDefaultDir = xe.InnerText;
                    }
                }
            }
            catch (Exception ex)
            {
                tool.Output.DumpWriteLine(ex.ToString());
                throw ex;
            }
        }
    }

    // 捕获用户的Ctrl + C
    public class ConsoleCtrl : IDisposable
    {
        public enum ConsoleEvent
        {
            CtrlC = 0, CtrlBreak = 1, CtrlClose = 2, CtrlLogoff = 5, CtrlShutdown = 6
        }

        public delegate void ControlEventHandler(ConsoleEvent consoleEvent);
        public event ControlEventHandler ControlEvent; ControlEventHandler eventHandler;

        public ConsoleCtrl()
        {
            eventHandler = new ControlEventHandler(Handler);
            SetConsoleCtrlHandler(eventHandler, true);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        void Dispose(bool disposing)
        {
            if (eventHandler != null)
            {
                SetConsoleCtrlHandler(eventHandler, false);
                eventHandler = null;
            }
        }

        private void Handler(ConsoleEvent consoleEvent)
        {
            if (ControlEvent != null)
                ControlEvent(consoleEvent);
        }

        [DllImport("kernel32.dll")]
        static extern bool SetConsoleCtrlHandler(ControlEventHandler e, bool add);
    }
}

